home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / ted5.zip / IGRABSRC.ZIP / FINISH.C < prev    next >
C/C++ Source or Header  |  1993-02-04  |  56KB  |  2,511 lines

  1. /////////////////////////////////////////////////////////
  2. //
  3. // Finish-Up Grabbing Stuff
  4. //
  5. /////////////////////////////////////////////////////////
  6. #include "igrab.h"
  7. #pragma hdrstop
  8.  
  9. long huge *fileoffs;
  10. int xms;
  11. unsigned numall;
  12. char grname[14],headname[14];
  13. long startlen,currentlen=0,oldlen=0,constcomp,constlen;
  14. unsigned vtab,start=0,allsparse=0;
  15. int oldhtab,oldvtab,xmsSource,xmsDest,xmsok;
  16.  
  17. /////////////////////////////////////////////////////////
  18. //
  19. // Here it is! Compresses and saves one big fat file!
  20. //
  21. /////////////////////////////////////////////////////////
  22. void FinishUp(void)
  23. {
  24.  SetupFinish();
  25.  CreateOffsets();
  26.  CompressSpecial();
  27.  CompressData();
  28.  CompressMisc();
  29.  CreateGraphFiles();
  30.  CreateHeaders();
  31.  UpdateWindow();
  32.  
  33.  //
  34.  // deallocate all the memory!
  35.  //
  36.  farfree((void far *)lbmscreen);
  37.  farfree((void far *)databuffer);
  38.  if (!leavetmp)
  39.    DeleteTmpFiles();
  40.  
  41.  CreateOBJs();
  42.  
  43.  //
  44.  // OUTTA HERE!
  45.  //
  46.  gotoxy(1,23);
  47.  poke(0,0x41a,peek(0,0x41c));    // clear keyboard
  48.  nosound();
  49.  exit(0);
  50. }
  51.  
  52.  
  53.  
  54. /////////////////////////////////////////////////////////
  55. //
  56. // Search the START string for the GRAB TYPE
  57. //
  58. /////////////////////////////////////////////////////////
  59. void FindType(char *string)
  60. {
  61.  if (!strncmp(string,"FONTM",5))
  62.    type=FONTMTYPE;
  63.  else
  64.  if (!strncmp(string,"FONT",4))
  65.     type=FONTTYPE;
  66.  else
  67.  
  68.  if (!strncmp(string,"TILE8M",6))
  69.     type=TILE8MTYPE;
  70.  else
  71.  if (!strncmp(string,"TILE8",5))
  72.     type=TILE8TYPE;
  73.  else
  74.  if (!strncmp(string,"ALT8M",5))
  75.     type=ALT8MTYPE;
  76.  else
  77.  if (!strncmp(string,"ALT8",4))
  78.     type=ALT8TYPE;
  79.  else
  80.  
  81.  if (!strncmp(string,"TILE16M",7))
  82.     type=TILE16MTYPE;
  83.  else
  84.  if (!strncmp(string,"TILE16",6))
  85.     type=TILE16TYPE;
  86.  else
  87.  if (!strncmp(string,"ALT16M",6))
  88.     type=ALT16MTYPE;
  89.  else
  90.  if (!strncmp(string,"ALT16",5))
  91.     type=ALT16TYPE;
  92.  else
  93.  
  94.  if (!strncmp(string,"TILE32M",7))
  95.     type=TILE32MTYPE;
  96.  else
  97.  if (!strncmp(string,"TILE32",6))
  98.     type=TILE32TYPE;
  99.  else
  100.  if (!strncmp(string,"ALT32M",6))
  101.     type=ALT32MTYPE;
  102.  else
  103.  if (!strncmp(string,"ALT32",5))
  104.     type=ALT32TYPE;
  105.  else
  106.  
  107.  if (!strncmp(string,"PICM",4))
  108.     type=PICMTYPE;
  109.  else
  110.  if (!strncmp(string,"PIC",3))
  111.     type=PICTYPE;
  112.  else
  113.  
  114.  if (!strncmp(string,"SPRITES",7))
  115.     type=SPRITETYPE;
  116.  else
  117.    {
  118.     char msg[80]="YOU CAN'T 'START ";
  119.  
  120.     strcat(msg,string);
  121.     strcat(msg,"'!");
  122.     errout(msg);
  123.    }
  124. }
  125.  
  126.  
  127. /////////////////////////////////////////////////////////
  128. //
  129. // Load an LBM screen (& maskscreen if applicable)
  130. //
  131. /////////////////////////////////////////////////////////
  132. void LoadKeyword(char *string,int grabbed)
  133. {
  134.  char huge *EGAscrn=MK_FP(0xa000,0),huge *CGAscrn=MK_FP(0xb800,0);
  135.  
  136.  //
  137.  // GET A KEYPRESS
  138.  //
  139.  if ((!fastgrab) && grabbed)
  140.    {
  141.     int key;
  142.  
  143.     if (bioskey(1))
  144.       bioskey(0);
  145.  
  146.     if (!SkipToStart)
  147.     {
  148.      key=bioskey(0);
  149.  
  150.      switch(key&255)
  151.      {
  152.       case 13:
  153.     SkipToStart=1;
  154.     break;
  155.       case 27:
  156.     errout("IGRAB ABORTED!");
  157.       case  9:
  158.     if (!noshow)
  159.     {
  160.      settext();
  161.      DispStatusScreen();
  162.      fastgrab=noshow=1;
  163.      poke(0,0x41a,peek(0,0x41c));    // clear keyboard
  164.     }
  165.      }
  166.     }
  167.    }
  168.  
  169.  switch(bioskey(1)>>8)
  170.  {
  171.   case 1:
  172.     errout("IGRAB ABORTED!");
  173.   case 15:
  174.     if (!noshow)
  175.     {
  176.      settext();
  177.      DispStatusScreen();
  178.      fastgrab=noshow=1;
  179.      poke(0,0x41a,peek(0,0x41c));    // clear keyboard
  180.     }
  181.  }
  182.  
  183.  //
  184.  // create screen suffix
  185.  //
  186.  strcpy(picname,path);
  187.  strcat(picname,string);
  188.  picname[strlen(picname)-2]=0;
  189.  switch(format[0])
  190.    {
  191.     case 'C': strcat(picname,"C.LBM");
  192.           break;
  193.     case 'E': strcat(picname,"E.LBM");
  194.           break;
  195.     case 'V': strcat(picname,"V.LBM");
  196.    }
  197.  
  198.  //
  199.  // all PIC,PICM,SPRITE data is flushed!
  200.  //
  201.  FlushData();
  202.  
  203.  //
  204.  // blast any buffers still intact
  205.  //
  206.  if (lbmscreen!=NULL)
  207.     farfree((void far *)lbmscreen);
  208.  if (maskscreen!=NULL)
  209.     farfree((void far *)maskscreen);
  210.  
  211.  lbmscreen=maskscreen=NULL;    // do this OR ELSE!
  212.  
  213.  lbmscreen=LoadLBM(picname,&CurrentLBM);
  214.  
  215.  //
  216.  // load the mask screen for current type,
  217.  // if applicable
  218.  //
  219.  if (!noshow && !SkipToStart)
  220.    //
  221.    // CLEAR THE SCREEN
  222.    //
  223.    switch(format[0])
  224.      {
  225.       case 'C':
  226.     for (i=0;i<0x4000;i++)
  227.       *(CGAscrn+i)=0;
  228.     break;
  229.  
  230.       case 'E':
  231.     outport(GCindex,GCmode);
  232.     outport(SCindex,SCmapmask + 0xf00);
  233.     for (i=0;i<8000;i++)
  234.       *(EGAscrn+i)=0;
  235.     break;
  236.       case 'V':
  237.     asm    pushf
  238.     asm    push    di
  239.     asm    mov    ax,0xa000
  240.     asm    mov    es,ax
  241.     asm    xor    di,di
  242.     asm    cld
  243.     asm    mov    cx,(320*200)/2
  244.     asm    xor    ax,ax
  245.     asm    rep stosw
  246.     asm    pop    di
  247.     asm    popf
  248.      }
  249.  
  250.  if (type==FONTMTYPE ||
  251.      type==TILE8MTYPE || type==ALT8MTYPE ||
  252.      type==TILE16MTYPE || type==ALT16MTYPE ||
  253.      type==TILE32MTYPE || type==ALT32MTYPE ||
  254.      type==PICMTYPE || type==SPRITETYPE)
  255.    {
  256.     char maskname[64];
  257.  
  258.     strcpy(maskname,path);
  259.     strcat(maskname,string);
  260.     maskname[strlen(maskname)-2]=0;
  261.     switch(format[0])
  262.       {
  263.        case 'C': strcat(maskname,"MC.LBM");
  264.          if (!noshow)
  265.            {
  266.             for (i=0;i<0x4000;i++)
  267.               *(CGAscrn+i)=0xaa;
  268.            }
  269.          break;
  270.  
  271.        case 'E': strcat(maskname,"ME.LBM");
  272.          if (!noshow)
  273.            {
  274.             outport(GCindex,GCmode);
  275.             ScreenColor=random(15)+1;
  276.             outport(SCindex,SCmapmask | (ScreenColor*256));
  277.             for (i=0;i<8000;i++)
  278.               *(EGAscrn+i)=0xff;
  279.            }
  280.          break;
  281.        case 'V': strcat(maskname,"MV.LBM");
  282.          if (!noshow)
  283.            {
  284.             char color=(random(13)+1)*16;
  285.  
  286.             asm        pushf
  287.             asm        push    di
  288.  
  289.             asm        cld
  290.             asm        mov    ax,0xa000
  291.             asm        mov    es,ax
  292.             asm        xor    di,di
  293.             asm        mov    al,[color]
  294.             asm        mov    bx,200/12
  295.             COLOOP:
  296.             asm        mov    cx,320*12
  297.             asm        rep stosb
  298.  
  299.             asm        inc    al
  300.             asm        dec    bx
  301.             asm        cmp    bx,0
  302.             asm        jnz    COLOOP
  303.  
  304.             asm        pop    di
  305.             asm        popf
  306.            }
  307.       }
  308.  
  309.     maskscreen=LoadLBM(maskname,&CurrentLBM);
  310.    }
  311.  
  312.  if (!noshow)
  313.    {
  314.     _BH=0;
  315.     _DX=0x1800;
  316.     _AH=2;
  317.     geninterrupt(0x10);
  318.     printf("%s - %s",typelist[type],picname);
  319.    }
  320.  else
  321.    {
  322.     cprintf("\r\nGrabbing from %s - %s",typelist[type],picname);
  323.     clreol();
  324.    }
  325.  
  326.  //
  327.  // MAKE SURE THE SCREEN JUST LOADED IS
  328.  // CORRECT FOR THE GRABBING VIDEOMODE!
  329.  //
  330.  switch(format[0])
  331.  {
  332.   case 'C':
  333.     if (CurrentLBM.planes!=2)
  334.       {
  335.        char erstr[200]="The screen '";
  336.        strcat(erstr,picname);
  337.        strcat(erstr,"' isn't a CGA screen!");
  338.        errout(erstr);
  339.       }
  340.     break;
  341.   case 'E':
  342.     if (CurrentLBM.planes!=4)
  343.       {
  344.        char erstr[200]="The screen '";
  345.        strcat(erstr,picname);
  346.        strcat(erstr,"' isn't an EGA screen!");
  347.        errout(erstr);
  348.       }
  349.     break;
  350.   case 'V':
  351.     if (CurrentLBM.planes!=8)
  352.       {
  353.        char erstr[200]="The screen '";
  354.        strcat(erstr,picname);
  355.        strcat(erstr,"' isn't a VGA screen!");
  356.        errout(erstr);
  357.       }
  358.  }
  359.  
  360.  
  361.  #if 0
  362.  //
  363.  // debug code to blast the screen in "lbmscreen" buffer
  364.  // to EGA screen
  365.  //
  366.  {
  367.   unsigned DSreg,SIreg,i,lwidth,height;
  368.   long size;
  369.  
  370.  
  371.   lwidth=CurrentLBM.width/8;
  372.   height=CurrentLBM.height;
  373.   size=lwidth*height;
  374.   outport(GCindex,GCmode);
  375.  
  376.   for (i=0;i<4;i++)
  377.     {
  378.       outport(SCindex,SCmapmask | (1<<i)*256);
  379.       DSreg=FP_SEG(lbmscreen)+(size*i)/16;
  380.       SIreg=FP_OFF(lbmscreen)+(size*i)&15;
  381.  
  382.       asm    push    ds
  383.       asm    mov    si,SIreg
  384.       asm    mov    ax,DSreg
  385.       asm    mov    ds,ax
  386.       asm    xor    di,di
  387.       asm    mov    ax,0xa000
  388.       asm    mov    es,ax
  389.       asm    cld
  390.       asm    mov    bx,[height]
  391.  
  392.       LOOP:
  393.  
  394.       asm    mov    cx,20
  395.       asm    rep movsw
  396.       asm    sub    si,40
  397.       asm    add    si,[lwidth]
  398.  
  399.       asm    dec    bx
  400.       asm    jnz    LOOP
  401.       asm    pop    ds
  402.     }
  403.   bioskey(0);
  404.  }
  405.  #endif
  406. }
  407.  
  408.  
  409. /////////////////////////////////////////////////////////
  410. //
  411. // See if there's enough Extended memory for FastCaching
  412. // If so, allocate the memory & load in the file to Extended Memory
  413. //
  414. /////////////////////////////////////////////////////////
  415. int CheckXMSamount(char *filename,int *handle1,int *handle2)
  416. {
  417.  long size,clen,coff;
  418.  
  419.  if (!xms)
  420.    return 0;
  421.  
  422.  size=filelen(filename);
  423.  if (1024L*XMSTotalFree()<2L*size)
  424.    {
  425.     *handle1=*handle2=0;
  426.     return 0;
  427.    }
  428.  
  429.  *handle1=XMSAllocate(size);
  430.  *handle2=XMSAllocate(size);
  431.  
  432.  coff=0;
  433.  do
  434.  {
  435.   clen=0x8000;
  436.   if (size<0x8000)
  437.     clen=size;
  438.  
  439.   LoadFile(filename,lbmscreen,coff,clen);
  440.   XMSmove(0,(long)lbmscreen,*handle1,coff,clen);
  441.   size-=0x8000;
  442.   coff+=clen;
  443.  } while(size>0);
  444.  
  445.  return 1;
  446. }
  447.  
  448.  
  449. /////////////////////////////////////////////////////////
  450. //
  451. // Free XMS buffers, if any
  452. //
  453. /////////////////////////////////////////////////////////
  454. void FreeXMSbuffs(int *handle1,int *handle2,char *filename,long start,long size)
  455. {
  456.  long clen,coff;
  457.  
  458.  if (!xms || (!*handle1 && !*handle2))
  459.    return;
  460.  
  461.  coff=0;
  462.  do
  463.  {
  464.   clen=0x8000;
  465.   if (size<0x8000)
  466.     clen=size;
  467.  
  468.   XMSmove(*handle2,coff,0,(long)lbmscreen,clen);
  469.   SaveFile(filename,lbmscreen,clen,start+coff);
  470.   size-=0x8000;
  471.   coff+=clen;
  472.  } while(size>0);
  473.  
  474.  XMSFreeMem(*handle1);
  475.  XMSFreeMem(*handle2);
  476.  *handle1=*handle2=0;
  477. }
  478.  
  479.  
  480. /////////////////////////////////////////////////////////
  481. //
  482. // Get file's length
  483. //
  484. /////////////////////////////////////////////////////////
  485. long filelen(char *string)
  486. {
  487.  long size;
  488.  int handle;
  489.  
  490.  if ((handle=_open(string,O_BINARY))<0)
  491.    return 0;
  492.  
  493.  size=filelength(handle);
  494.  close(handle);
  495.  return size;
  496. }
  497.  
  498.  
  499. /////////////////////////////////////////////////////////
  500. //
  501. // Move status screen to text screen
  502. //
  503. /////////////////////////////////////////////////////////
  504. void DispStatusScreen(void)
  505. {
  506.  _fmemcpy((void far *)MK_FP(0xb800,0),&SCREEN+7,4000);
  507.  
  508.  window(1,1,80,25);
  509.  gotoxy(43,4);
  510.  cprintf("%s",VERSION);
  511.  gotoxy(46,5);
  512.  cprintf("%cGA",format[0]);
  513.  window(2,8,78,19);
  514. }
  515.  
  516.  
  517. /////////////////////////////////////////////////////////
  518. //
  519. // Create .H,.EQU files
  520. //
  521. /////////////////////////////////////////////////////////
  522. void CreateHeaders(void)
  523. {
  524.  char str[50],temp[5];
  525.  long start;
  526.  int chnk=0;
  527.  
  528.  
  529.  time(&tblock);
  530.  
  531.  strcpy(dest,"GFX?_ext.H");
  532.  dest[3]=format[0];
  533.  strncpy(dest+5,ext,3);
  534.  unlink(dest);
  535.  if ((fp=fopen(dest,"wt"))==NULL)
  536.    {
  537.     char msg[80]="Couldn't create '";
  538.  
  539.     strcat(msg,dest);
  540.     strcat(msg,"'!");
  541.     errout(msg);
  542.    }
  543.  
  544.  fprintf(fp,"//////////////////////////////////////\n");
  545.  fprintf(fp,"//\n");
  546.  fprintf(fp,"// Graphics .H file for .%s\n",ext);
  547.  fprintf(fp,"// IGRAB-ed on %s",ctime(&tblock));
  548.  fprintf(fp,"//\n");
  549.  fprintf(fp,"//////////////////////////////////////\n\n");
  550.  
  551.  fprintf(fp,"typedef enum {\n");
  552.  
  553.  for (i=0;i<Data[PIC].num;i++)
  554.    {
  555.     int end;
  556.  
  557.     if (ChunkStart[chnk]+Data[ChunkType[chnk]].offset==i+Data[PIC].offset)
  558.       {
  559.        fprintf(fp,"\t\t// Lump Start\n");
  560.        chnk++;
  561.       }
  562.  
  563.     _fmemcpy((char far *)str,(char far *)PicNames+i*NAMELEN,50);
  564.     strcat(str,"PIC");
  565.     if (!i)
  566.       fprintf(fp,"\t\t%s=%d,\n",str,i+Data[PIC].offset);
  567.     else
  568.     {
  569.      strcat(str,",");
  570.      while(strlen(str)<NAMELEN+5)
  571.        strcat(str," ");
  572.       fprintf(fp,"\t\t%s// %d\n",str,i+Data[PIC].offset);
  573.     }
  574.    }
  575.  
  576.  fprintf(fp,"\n");
  577.  
  578.  for (i=0;i<Data[PICM].num;i++)
  579.    {
  580.     int end;
  581.  
  582.     if (ChunkStart[chnk]+Data[ChunkType[chnk]].offset==i+Data[PICM].offset)
  583.       {
  584.        fprintf(fp,"\t\t// Lump Start\n");
  585.        chnk++;
  586.       }
  587.  
  588.     _fmemcpy((char far *)str,(char far *)PicMNames+i*NAMELEN,50);
  589.     strcat(str,"PICM");
  590.     if (!i)
  591.       fprintf(fp,"\t\t%s=%d,\n",str,i+Data[PICM].offset);
  592.     else
  593.     {
  594.      strcat(str,",");
  595.      while(strlen(str)<NAMELEN+5)
  596.        strcat(str," ");
  597.       fprintf(fp,"\t\t%s// %d\n",str,i+Data[PICM].offset);
  598.     }
  599.    }
  600.  
  601.  fprintf(fp,"\n");
  602.  
  603.  for (i=0;i<Data[SPRITE].num;i++)
  604.    {
  605.     int end;
  606.  
  607.     if (ChunkStart[chnk]+Data[ChunkType[chnk]].offset==i+Data[SPRITE].offset)
  608.       {
  609.        fprintf(fp,"\t\t// Lump Start\n");
  610.        chnk++;
  611.       }
  612.  
  613.     _fmemcpy((char far *)str,(char far *)SpriteNames+i*NAMELEN,50);
  614.     strcat(str,"SPR");
  615.     if (!i)
  616.       fprintf(fp,"\t\t%s=%d,\n",str,i+Data[SPRITE].offset);
  617.     else
  618.     {
  619.      strcat(str,",");
  620.      while(strlen(str)<NAMELEN+5)
  621.        strcat(str," ");
  622.       fprintf(fp,"\t\t%s// %d\n",str,i+Data[SPRITE].offset);
  623.     }
  624.    }
  625.  
  626.  fprintf(fp,"\n");
  627.  
  628.  for (i=0;i<NumMisc;i++)
  629.    {
  630.     int end;
  631.  
  632.     _fmemcpy((char far *)str,(char far *)MiscNames+i*NAMELEN,50);
  633.     if (!i)
  634.       fprintf(fp,"\t\t%s=%d,\n",str,i+Data[TILE32M].offset+Data[TILE32M].num);
  635.     else
  636.     {
  637.      strcat(str,",");
  638.      while(strlen(str)<NAMELEN+5)
  639.        strcat(str," ");
  640.       fprintf(fp,"\t\t%s// %d\n",str,i+Data[TILE32M].offset+Data[TILE32M].num);
  641.     }
  642.    }
  643.  
  644.  fprintf(fp,"\t\tENUMEND\n\t     } graphicnums;\n");
  645.  fprintf(fp,"\n");
  646.  
  647.  //
  648.  // output the LUMP defines
  649.  //
  650.  fprintf(fp,"//\n// Data LUMPs\n//\n");
  651.  
  652.  for (i=0;i<whichchunk;i++)
  653.    {
  654.     int end;
  655.  
  656.     for (j=0;j<_fstrlen((char far *)ChunkNames+i*CHKNAMELEN);j++)
  657.       if (*(ChunkNames+i*CHKNAMELEN+j)=='\r')
  658.     {
  659.      *(ChunkNames+i*CHKNAMELEN+j)=0;
  660.      break;
  661.     }
  662.  
  663.     _fmemcpy((char far *)str,(char far *)ChunkNames+i*CHKNAMELEN,50);
  664.     strcat(str,"_LUMP_START");
  665.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  666.       strcat(str,"\x9");
  667.     fprintf(fp,"#define %s%d\n",str,ChunkStart[i]+Data[ChunkType[i]].offset);
  668.  
  669.     _fmemcpy((char far *)str,(char far *)ChunkNames+i*CHKNAMELEN,50);
  670.     strcat(str,"_LUMP_END");
  671.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  672.       strcat(str,"\x9");
  673.     fprintf(fp,"#define %s%d\n\n",str,ChunkEnd[i]+Data[ChunkType[i]].offset);
  674.    }
  675.  
  676.  fprintf(fp,"\n");
  677.  
  678.  //
  679.  // output the #defines for NUM
  680.  //
  681.  fprintf(fp,"//\n// Amount of each data item\n//\n");
  682.  
  683.  strcpy(str,"#define NUMCHUNKS    ");
  684.  itoa(numall,temp,10);
  685.  strcat(str,temp);
  686.  fprintf(fp,"%s\n",str);
  687.  
  688.  strcpy(str,"#define NUMFONT      ");
  689.  itoa(Data[FONT].num,temp,10);
  690.  strcat(str,temp);
  691.  fprintf(fp,"%s\n",str);
  692.  
  693.  strcpy(str,"#define NUMFONTM     ");
  694.  itoa(Data[FONTM].num,temp,10);
  695.  strcat(str,temp);
  696.  fprintf(fp,"%s\n",str);
  697.  
  698.  strcpy(str,"#define NUMPICS      ");
  699.  itoa(Data[PIC].num,temp,10);
  700.  strcat(str,temp);
  701.  fprintf(fp,"%s\n",str);
  702.  
  703.  strcpy(str,"#define NUMPICM      ");
  704.  itoa(Data[PICM].num,temp,10);
  705.  strcat(str,temp);
  706.  fprintf(fp,"%s\n",str);
  707.  
  708.  strcpy(str,"#define NUMSPRITES   ");
  709.  itoa(Data[SPRITE].num,temp,10);
  710.  strcat(str,temp);
  711.  fprintf(fp,"%s\n",str);
  712.  
  713.  strcpy(str,"#define NUMTILE8     ");
  714.  itoa(Data[TILE8].num,temp,10);
  715.  strcat(str,temp);
  716.  fprintf(fp,"%s\n",str);
  717.  
  718.  strcpy(str,"#define NUMTILE8M    ");
  719.  itoa(Data[TILE8M].num,temp,10);
  720.  strcat(str,temp);
  721.  fprintf(fp,"%s\n",str);
  722.  
  723.  strcpy(str,"#define NUMTILE16    ");
  724.  itoa(Data[TILE16].num,temp,10);
  725.  strcat(str,temp);
  726.  fprintf(fp,"%s\n",str);
  727.  
  728.  strcpy(str,"#define NUMTILE16M   ");
  729.  itoa(Data[TILE16M].num,temp,10);
  730.  strcat(str,temp);
  731.  fprintf(fp,"%s\n",str);
  732.  
  733.  strcpy(str,"#define NUMTILE32    ");
  734.  itoa(Data[TILE32].num,temp,10);
  735.  strcat(str,temp);
  736.  fprintf(fp,"%s\n",str);
  737.  
  738.  strcpy(str,"#define NUMTILE32M   ");
  739.  itoa(Data[TILE32M].num,temp,10);
  740.  strcat(str,temp);
  741.  fprintf(fp,"%s\n",str);
  742.  
  743.  strcpy(str,"#define NUMEXTERNS   ");
  744.  itoa(NumMisc,temp,10);
  745.  strcat(str,temp);
  746.  fprintf(fp,"%s\n",str);
  747.  
  748.  //
  749.  // output the #defines for START
  750.  //
  751.  fprintf(fp,"//\n// File offsets for data items\n//\n");
  752.  
  753.  //
  754.  // SPECIAL DATA CHUNKS
  755.  //
  756.  start=0;
  757.  if (Data[PIC].num)
  758.    {
  759.     strcpy(str,"#define STRUCTPIC    ");
  760.     itoa(start,temp,10);
  761.     strcat(str,temp);
  762.     fprintf(fp,"%s\n",str);
  763.     start++;
  764.    }
  765.  if (Data[PICM].num)
  766.    {
  767.     strcpy(str,"#define STRUCTPICM   ");
  768.     itoa(start,temp,10);
  769.     strcat(str,temp);
  770.     fprintf(fp,"%s\n",str);
  771.     start++;
  772.    }
  773.  if (Data[SPRITE].num)
  774.    {
  775.     strcpy(str,"#define STRUCTSPRITE ");
  776.     itoa(start,temp,10);
  777.     strcat(str,temp);
  778.     fprintf(fp,"%s\n",str);
  779.     start++;
  780.    }
  781.  
  782.  if (bit && T8whichbit)
  783.    {
  784.     strcpy(str,"#define T8MBITARRAY  ");
  785.     itoa(start,temp,10);
  786.     strcat(str,temp);
  787.     fprintf(fp,"%s\n",str);
  788.     start++;
  789.    }
  790.  
  791.  if (bit && T16whichbit)
  792.    {
  793.     strcpy(str,"#define T16MBITARRAY ");
  794.     itoa(start,temp,10);
  795.     strcat(str,temp);
  796.     fprintf(fp,"%s\n",str);
  797.     start++;
  798.    }
  799.  
  800.  if (bit && T32whichbit)
  801.    {
  802.     strcpy(str,"#define T32MBITARRAY ");
  803.     itoa(start,temp,10);
  804.     strcat(str,temp);
  805.     fprintf(fp,"%s\n",str);
  806.     start++;
  807.    }
  808.  
  809.  //
  810.  // GRAPHIC DATA CHUNKS
  811.  //
  812.  if (start)
  813.    fprintf(fp,"\n");
  814.  
  815.  strcpy(str,"#define STARTFONT    ");
  816.  ltoa(Data[FONT].offset,temp,10);
  817.  strcat(str,temp);
  818.  fprintf(fp,"%s\n",str);
  819.  
  820.  strcpy(str,"#define STARTFONTM   ");
  821.  ltoa(Data[FONTM].offset,temp,10);
  822.  strcat(str,temp);
  823.  fprintf(fp,"%s\n",str);
  824.  
  825.  strcpy(str,"#define STARTPICS    ");
  826.  ltoa(Data[PIC].offset,temp,10);
  827.  strcat(str,temp);
  828.  fprintf(fp,"%s\n",str);
  829.  
  830.  strcpy(str,"#define STARTPICM    ");
  831.  ltoa(Data[PICM].offset,temp,10);
  832.  strcat(str,temp);
  833.  fprintf(fp,"%s\n",str);
  834.  
  835.  strcpy(str,"#define STARTSPRITES ");
  836.  ltoa(Data[SPRITE].offset,temp,10);
  837.  strcat(str,temp);
  838.  fprintf(fp,"%s\n",str);
  839.  
  840.  strcpy(str,"#define STARTTILE8   ");
  841.  ltoa(Data[TILE8].offset,temp,10);
  842.  strcat(str,temp);
  843.  fprintf(fp,"%s\n",str);
  844.  
  845.  strcpy(str,"#define STARTTILE8M  ");
  846.  ltoa(Data[TILE8M].offset,temp,10);
  847.  strcat(str,temp);
  848.  fprintf(fp,"%s\n",str);
  849.  
  850.  strcpy(str,"#define STARTTILE16  ");
  851.  ltoa(Data[TILE16].offset,temp,10);
  852.  strcat(str,temp);
  853.  fprintf(fp,"%s\n",str);
  854.  
  855.  strcpy(str,"#define STARTTILE16M ");
  856.  ltoa(Data[TILE16M].offset,temp,10);
  857.  strcat(str,temp);
  858.  fprintf(fp,"%s\n",str);
  859.  
  860.  strcpy(str,"#define STARTTILE32  ");
  861.  ltoa(Data[TILE32].offset,temp,10);
  862.  strcat(str,temp);
  863.  fprintf(fp,"%s\n",str);
  864.  
  865.  strcpy(str,"#define STARTTILE32M ");
  866.  ltoa(Data[TILE32M].offset,temp,10);
  867.  strcat(str,temp);
  868.  fprintf(fp,"%s\n",str);
  869.  
  870.  strcpy(str,"#define STARTEXTERNS ");
  871.  ltoa(Data[TILE32M].offset+Data[TILE32M].num,temp,10);
  872.  strcat(str,temp);
  873.  fprintf(fp,"%s\n",str);
  874.  
  875.  //
  876.  // finish up .H
  877.  //
  878.  fprintf(fp,"\n");
  879.  fprintf(fp,"//\n");
  880.  fprintf(fp,"// Thank you for using IGRAB!\n");
  881.  fprintf(fp,"//\n");
  882.  fclose(fp);
  883.  
  884.  
  885.  
  886.  //
  887.  // Create .EQU ASM file
  888.  //
  889.  
  890.  time(&tblock);
  891.  
  892.  strcpy(dest,"GFX?_ext.EQU");
  893.  dest[3]=format[0];
  894.  strncpy(dest+5,ext,3);
  895.  unlink(dest);
  896.  if ((fp=fopen(dest,"wt"))==NULL)
  897.    {
  898.     char msg[80]="Couldn't create '";
  899.  
  900.     strcat(msg,dest);
  901.     strcat(msg,"'!");
  902.     errout(msg);
  903.    }
  904.  
  905.  fprintf(fp,";=====================================\n");
  906.  fprintf(fp,";\n");
  907.  fprintf(fp,"; Graphics .EQU file for .%s\n",ext);
  908.  fprintf(fp,"; IGRAB-ed on %s",ctime(&tblock));
  909.  fprintf(fp,";\n");
  910.  fprintf(fp,";=====================================\n\n");
  911.  
  912.  for (i=0;i<Data[PIC].num;i++)
  913.    {
  914.     _fmemcpy((char far *)str,(char far *)PicNames+i*NAMELEN,50);
  915.     strcat(str,"PIC");
  916.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  917.       strcat(str,"\x9");
  918.     fprintf(fp,"%s=    %d\n",str,i+Data[PIC].offset);
  919.    }
  920.  
  921.  fprintf(fp,"\n");
  922.  
  923.  for (i=0;i<Data[PICM].num;i++)
  924.    {
  925.     _fmemcpy((char far *)str,(char far *)PicMNames+i*NAMELEN,50);
  926.     strcat(str,"PICM");
  927.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  928.       strcat(str,"\x9");
  929.     fprintf(fp,"%s=    %d\n",str,i+Data[PICM].offset);
  930.    }
  931.  
  932.  fprintf(fp,"\n");
  933.  
  934.  for (i=0;i<Data[SPRITE].num;i++)
  935.    {
  936.     _fmemcpy((char far *)str,(char far *)SpriteNames+i*NAMELEN,50);
  937.     strcat(str,"SPR");
  938.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  939.       strcat(str,"\x9");
  940.     fprintf(fp,"%s=    %d\n",str,i+Data[SPRITE].offset);
  941.    }
  942.  
  943.  fprintf(fp,"\n");
  944.  
  945.  for (i=0;i<NumMisc;i++)
  946.    {
  947.     _fmemcpy((char far *)str,(char far *)MiscNames+i*NAMELEN,50);
  948.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  949.       strcat(str,"\x9");
  950.     fprintf(fp,"%s=    %d\n",str,i+Data[TILE32M].offset+Data[TILE32M].num);
  951.    }
  952.  
  953.  fprintf(fp,"\n");
  954.  
  955.  for (i=0;i<whichchunk;i++)
  956.    {
  957.     for (j=0;j<_fstrlen((char far *)ChunkNames+i*CHKNAMELEN);j++)
  958.       if (*(ChunkNames+i*CHKNAMELEN+j)=='\r')
  959.     {
  960.      *(ChunkNames+i*CHKNAMELEN+j)=0;
  961.      break;
  962.     }
  963.  
  964.     _fmemcpy((char far *)str,(char far *)ChunkNames+i*CHKNAMELEN,50);
  965.     strcat(str,"_LUMP_START");
  966.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  967.       strcat(str,"\x9");
  968.     fprintf(fp,"%s=\x9%d\n",str,ChunkStart[i]+Data[ChunkType[i]].offset);
  969.  
  970.     _fmemcpy((char far *)str,(char far *)ChunkNames+i*CHKNAMELEN,50);
  971.     strcat(str,"_LUMP_END");
  972.     for (end=(48-strlen(str)-9)/8,j=0;j<end;j++)
  973.       strcat(str,"\x9");
  974.     fprintf(fp,"%s=\x9%d\n\n",str,ChunkEnd[i]+Data[ChunkType[i]].offset);
  975.    }
  976.  
  977.  fprintf(fp,"\n");
  978.  
  979.  //
  980.  // output the #defines for NUM
  981.  //
  982.  fprintf(fp,";\n; Amount of each data item\n;\n");
  983.  
  984.  strcpy(str,"NUMCHUNKS\x9=\x9");
  985.  itoa(numall,temp,10);
  986.  strcat(str,temp);
  987.  fprintf(fp,"%s\n",str);
  988.  
  989.  strcpy(str,"NUMFONT  \x9=\x9");
  990.  itoa(Data[FONT].num,temp,10);
  991.  strcat(str,temp);
  992.  fprintf(fp,"%s\n",str);
  993.  
  994.  strcpy(str,"NUMFONTM  \x9=\x9");
  995.  itoa(Data[FONTM].num,temp,10);
  996.  strcat(str,temp);
  997.  fprintf(fp,"%s\n",str);
  998.  
  999.  strcpy(str,"NUMPICS  \x9=\x9");
  1000.  itoa(Data[PIC].num,temp,10);
  1001.  strcat(str,temp);
  1002.  fprintf(fp,"%s\n",str);
  1003.  
  1004.  strcpy(str,"NUMPICM  \x9=\x9");
  1005.  itoa(Data[PICM].num,temp,10);
  1006.  strcat(str,temp);
  1007.  fprintf(fp,"%s\n",str);
  1008.  
  1009.  strcpy(str,"NUMSPRITES  \x9=\x9");
  1010.  itoa(Data[SPRITE].num,temp,10);
  1011.  strcat(str,temp);
  1012.  fprintf(fp,"%s\n",str);
  1013.  
  1014.  strcpy(str,"NUMTILE8  \x9=\x9");
  1015.  itoa(Data[TILE8].num,temp,10);
  1016.  strcat(str,temp);
  1017.  fprintf(fp,"%s\n",str);
  1018.  
  1019.  strcpy(str,"NUMTILE8M  \x9=\x9");
  1020.  itoa(Data[TILE8M].num,temp,10);
  1021.  strcat(str,temp);
  1022.  fprintf(fp,"%s\n",str);
  1023.  
  1024.  strcpy(str,"NUMTILE16  \x9=\x9");
  1025.  itoa(Data[TILE16].num,temp,10);
  1026.  strcat(str,temp);
  1027.  fprintf(fp,"%s\n",str);
  1028.  
  1029.  strcpy(str,"NUMTILE16M  \x9=\x9");
  1030.  itoa(Data[TILE16M].num,temp,10);
  1031.  strcat(str,temp);
  1032.  fprintf(fp,"%s\n",str);
  1033.  
  1034.  strcpy(str,"NUMTILE32  \x9=\x9");
  1035.  itoa(Data[TILE32].num,temp,10);
  1036.  strcat(str,temp);
  1037.  fprintf(fp,"%s\n",str);
  1038.  
  1039.  strcpy(str,"NUMTILE32M  \x9=\x9");
  1040.  itoa(Data[TILE32M].num,temp,10);
  1041.  strcat(str,temp);
  1042.  fprintf(fp,"%s\n",str);
  1043.  
  1044.  strcpy(str,"NUMEXTERN  \x9=\x9");
  1045.  itoa(NumMisc,temp,10);
  1046.  strcat(str,temp);
  1047.  fprintf(fp,"%s\n",str);
  1048.  
  1049.  //
  1050.  // output the #defines for START
  1051.  //
  1052.  fprintf(fp,";\n; File offsets for data items\n;\n");
  1053.  
  1054.  //
  1055.  // SPECIAL CHUNKS
  1056.  //
  1057.  start=0;
  1058.  if (Data[PIC].num)
  1059.    {
  1060.     strcpy(str,"STRUCTPIC  \x9=\x9");
  1061.     itoa(start,temp,10);
  1062.     strcat(str,temp);
  1063.     fprintf(fp,"%s\n",str);
  1064.     start++;
  1065.    }
  1066.  if (Data[PICM].num)
  1067.    {
  1068.     strcpy(str,"STRUCTPICM  \x9=\x9");
  1069.     itoa(start,temp,10);
  1070.     strcat(str,temp);
  1071.     fprintf(fp,"%s\n",str);
  1072.     start++;
  1073.    }
  1074.  if (Data[SPRITE].num)
  1075.    {
  1076.     strcpy(str,"STRUCTSPRITE  \x9=\x9");
  1077.     itoa(start,temp,10);
  1078.     strcat(str,temp);
  1079.     fprintf(fp,"%s\n",str);
  1080.     start++;
  1081.    }
  1082.  
  1083.  if (bit && T8whichbit)
  1084.    {
  1085.     strcpy(str,"T8MBITARRAY   \x9=\x9");
  1086.     itoa(start,temp,10);
  1087.     strcat(str,temp);
  1088.     fprintf(fp,"%s\n",str);
  1089.     start++;
  1090.    }
  1091.  
  1092.  if (bit && T16whichbit)
  1093.    {
  1094.     strcpy(str,"T16MBITARRAY  \x9=\x9");
  1095.     itoa(start,temp,10);
  1096.     strcat(str,temp);
  1097.     fprintf(fp,"%s\n",str);
  1098.     start++;
  1099.    }
  1100.  
  1101.  if (bit && T32whichbit)
  1102.    {
  1103.     strcpy(str,"T32MBITARRAY  \x9=\x9");
  1104.     itoa(start,temp,10);
  1105.     strcat(str,temp);
  1106.     fprintf(fp,"%s\n",str);
  1107.     start++;
  1108.    }
  1109.  
  1110.  //
  1111.  // GRAPHIC CHUNKS
  1112.  //
  1113.  if (start)
  1114.    fprintf(fp,"\n");
  1115.  
  1116.  strcpy(str,"STARTFONT  \x9=\x9");
  1117.  ltoa(Data[FONT].offset,temp,10);
  1118.  strcat(str,temp);
  1119.  fprintf(fp,"%s\n",str);
  1120.  
  1121.  strcpy(str,"STARTFONTM  \x9=\x9");
  1122.  ltoa(Data[FONTM].offset,temp,10);
  1123.  strcat(str,temp);
  1124.  fprintf(fp,"%s\n",str);
  1125.  
  1126.  strcpy(str,"STARTPICS  \x9=\x9");
  1127.  ltoa(Data[PIC].offset,temp,10);
  1128.  strcat(str,temp);
  1129.  fprintf(fp,"%s\n",str);
  1130.  
  1131.  strcpy(str,"STARTPICM  \x9=\x9");
  1132.  ltoa(Data[PICM].offset,temp,10);
  1133.  strcat(str,temp);
  1134.  fprintf(fp,"%s\n",str);
  1135.  
  1136.  strcpy(str,"STARTSPRITES  \x9=\x9");
  1137.  ltoa(Data[SPRITE].offset,temp,10);
  1138.  strcat(str,temp);
  1139.  fprintf(fp,"%s\n",str);
  1140.  
  1141.  strcpy(str,"STARTTILE8  \x9=\x9");
  1142.  ltoa(Data[TILE8].offset,temp,10);
  1143.  strcat(str,temp);
  1144.  fprintf(fp,"%s\n",str);
  1145.  
  1146.  strcpy(str,"STARTTILE8M  \x9=\x9");
  1147.  ltoa(Data[TILE8M].offset,temp,10);
  1148.  strcat(str,temp);
  1149.  fprintf(fp,"%s\n",str);
  1150.  
  1151.  strcpy(str,"STARTTILE16  \x9=\x9");
  1152.  ltoa(Data[TILE16].offset,temp,10);
  1153.  strcat(str,temp);
  1154.  fprintf(fp,"%s\n",str);
  1155.  
  1156.  strcpy(str,"STARTTILE16M  \x9=\x9");
  1157.  ltoa(Data[TILE16M].offset,temp,10);
  1158.  strcat(str,temp);
  1159.  fprintf(fp,"%s\n",str);
  1160.  
  1161.  strcpy(str,"STARTTILE32  \x9=\x9");
  1162.  ltoa(Data[TILE32].offset,temp,10);
  1163.  strcat(str,temp);
  1164.  fprintf(fp,"%s\n",str);
  1165.  
  1166.  strcpy(str,"STARTTILE32M  \x9=\x9");
  1167.  ltoa(Data[TILE32M].offset,temp,10);
  1168.  strcat(str,temp);
  1169.  fprintf(fp,"%s\n",str);
  1170.  
  1171.  strcpy(str,"STARTEXTERN  \x9=\x9");
  1172.  ltoa(Data[TILE32M].offset+Data[TILE32M].num,temp,10);
  1173.  strcat(str,temp);
  1174.  fprintf(fp,"%s\n",str);
  1175.  
  1176.  //
  1177.  // finish up .EQU
  1178.  //
  1179.  fprintf(fp,"\n");
  1180.  fprintf(fp,";\n");
  1181.  fprintf(fp,"; Thank you for using IGRAB!\n");
  1182.  fprintf(fp,";\n");
  1183.  fclose(fp);
  1184. }
  1185.  
  1186.  
  1187. /////////////////////////////////////////////////////////
  1188. //
  1189. // Compress all the different data types
  1190. //
  1191. /////////////////////////////////////////////////////////
  1192. void CompressData(void)
  1193. {
  1194.  //
  1195.  // Compress the different data types
  1196.  //
  1197.  oldhtab=wherex();
  1198.  oldvtab=wherey();
  1199.  gotoxy(oldhtab,oldvtab);
  1200.  
  1201.  CompressFonts();
  1202.  CompressPics();
  1203.  CompressSprites();
  1204.  Compress8();
  1205.  Compress16();
  1206.  Compress32();
  1207.  
  1208.  //
  1209.  // MAKE SURE WE WRITE OUT A FINAL "OFFSET"
  1210.  // FOR LENGTH-FINDING PURPOSES!
  1211.  //
  1212.  fileoffs[Data[TILE32M].offset+Data[TILE32M].num]=currentlen;
  1213. }
  1214.  
  1215.  
  1216. /////////////////////////////////////////////////////////
  1217. //
  1218. // Compress the FONT/Ms
  1219. //
  1220. /////////////////////////////////////////////////////////
  1221. void CompressFonts(void)
  1222. {
  1223.  if (Data[FONT].num)
  1224.    {
  1225.     constlen=constcomp=0;
  1226.     gotoxy(30,wherey());
  1227.     printf("Compressing...");
  1228.  
  1229.     //
  1230.     // Stick Id Software ID bytes in!!!
  1231.     //
  1232.     SaveFile(grname,"!ID!",4,currentlen);
  1233.     currentlen+=4;
  1234.  
  1235.     for (i=0;i<Data[FONT].num;i++)
  1236.       {
  1237.        long newlen,length=FontOffs[i+1]-FontOffs[i];
  1238.  
  1239.        gotoxy(44,wherey());
  1240.        printf("%d",i+1);
  1241.  
  1242.        constlen+=length;
  1243.        oldlen+=length;
  1244.        fileoffs[Data[FONT].offset+i]=currentlen;
  1245.        *(long huge *)databuffer=length;
  1246.        LoadFile("FONT.TMP",lbmscreen,FontOffs[i],length);
  1247.        newlen=HuffCompress(lbmscreen,length,databuffer+4);
  1248.        SaveFile(grname,databuffer,newlen+4,currentlen);
  1249.        currentlen+=newlen+4;
  1250.        if ((bioskey(1)>>8)==1)
  1251.      {
  1252.       clrscr();
  1253.       errout("Aborted!");
  1254.      }
  1255.        constcomp+=newlen;
  1256.       }
  1257.     gotoxy(30,wherey());
  1258.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1259.     clreol();
  1260.    }
  1261.  cprintf("\n\r");
  1262.  
  1263.  if (Data[FONTM].num)
  1264.    {
  1265.     constlen=constcomp=0;
  1266.     gotoxy(30,wherey());
  1267.     printf("Compressing...");
  1268.  
  1269.     //
  1270.     // Stick Id Software ID bytes in!!!
  1271.     //
  1272.     SaveFile(grname,"!ID!",4,currentlen);
  1273.     currentlen+=4;
  1274.  
  1275.     for (i=0;i<Data[FONTM].num;i++)
  1276.       {
  1277.        long newlen,length=FontMOffs[i+1]-FontMOffs[i];
  1278.  
  1279.        gotoxy(44,wherey());
  1280.        printf("%d",i+1);
  1281.  
  1282.        constlen+=length;
  1283.        oldlen+=length;
  1284.        fileoffs[Data[FONTM].offset+i]=currentlen;
  1285.        *(long huge *)databuffer=length;
  1286.        LoadFile("FONTM.TMP",lbmscreen,FontMOffs[i],length);
  1287.        newlen=HuffCompress(lbmscreen,length,databuffer+4);
  1288.        SaveFile(grname,databuffer,newlen+4,currentlen);
  1289.        currentlen+=newlen+4;
  1290.        if ((bioskey(1)>>8)==1)
  1291.      {
  1292.       clrscr();
  1293.       errout("Aborted!");
  1294.      }
  1295.        constcomp+=newlen;
  1296.       }
  1297.     gotoxy(30,wherey());
  1298.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1299.     clreol();
  1300.    }
  1301.  cprintf("\n\r");
  1302. }
  1303.  
  1304.  
  1305. /////////////////////////////////////////////////////////
  1306. //
  1307. // Compress the PIC/Ms
  1308. //
  1309. /////////////////////////////////////////////////////////
  1310. void CompressPics(void)
  1311. {
  1312.  if (Data[PIC].num)
  1313.    {
  1314.     long newlen,length;
  1315.  
  1316.     constlen=constcomp=0;
  1317.     gotoxy(30,wherey());
  1318.     printf("Compressing...");
  1319.  
  1320.     //
  1321.     // Stick Id Software ID bytes in!!!
  1322.     //
  1323.     SaveFile(grname,"!ID!",4,currentlen);
  1324.     currentlen+=4;
  1325.  
  1326.     //
  1327.     // Check for enough Extended memory for this...
  1328.     //
  1329.     xmsok=CheckXMSamount("PIC.TMP",&xmsSource,&xmsDest);
  1330.     if (xmsok)
  1331.       {
  1332.        printf("       (XMS cache)");
  1333.        startlen=currentlen;
  1334.       }
  1335.  
  1336.     for (i=0;i<Data[PIC].num;i++)
  1337.       {
  1338.        gotoxy(44,wherey());
  1339.        printf("%d",i+1);
  1340.  
  1341.        length=PicOffs[i+1]-PicOffs[i];
  1342.        if (length>comp_size)
  1343.      errout("PIC is too big for the allocated buffer (compression)!");
  1344.        constlen+=length;
  1345.        oldlen+=length;
  1346.        fileoffs[Data[PIC].offset+i]=currentlen;
  1347.        *(long huge *)databuffer=length;
  1348.  
  1349.        if (!xmsok)
  1350.      LoadFile("PIC.TMP",lbmscreen,PicOffs[i],length);
  1351.        else
  1352.      XMSmove(xmsSource,PicOffs[i],0,(long)lbmscreen,length);
  1353.  
  1354.        //
  1355.        // Munge VGA ModeX graphics?
  1356.        //
  1357.        if (ModeX)
  1358.      VL_MungePic((unsigned char far *)lbmscreen,(PicTable+i)->width,(PicTable+i)->height);
  1359.  
  1360.        newlen=HuffCompress(lbmscreen,length,databuffer+4)+4;
  1361.  
  1362.        if (!xmsok)
  1363.      SaveFile(grname,databuffer,newlen,currentlen);
  1364.        else
  1365.      XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1366.  
  1367.        currentlen+=newlen;
  1368.        constcomp+=newlen;
  1369.        if ((bioskey(1)>>8)==1)
  1370.      {
  1371.       clrscr();
  1372.       errout("Aborted!");
  1373.      }
  1374.       }
  1375.  
  1376.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1377.  
  1378.     gotoxy(30,wherey());
  1379.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1380.     clreol();
  1381.    }
  1382.  cprintf("\n\r");
  1383.  
  1384.  if (Data[PICM].num)
  1385.    {
  1386.     long newlen,length;
  1387.  
  1388.     constlen=constcomp=0;
  1389.     gotoxy(30,wherey());
  1390.     printf("Compressing...");
  1391.  
  1392.  
  1393.     //
  1394.     // Stick Id Software ID bytes in!!!
  1395.     //
  1396.     SaveFile(grname,"!ID!",4,currentlen);
  1397.     currentlen+=4;
  1398.  
  1399.     xmsok=CheckXMSamount("PICM.TMP",&xmsSource,&xmsDest);
  1400.     if (xmsok)
  1401.       {
  1402.        printf("       (XMS cache)");
  1403.        startlen=currentlen;
  1404.       }
  1405.  
  1406.     for (i=0;i<Data[PICM].num;i++)
  1407.       {
  1408.        gotoxy(44,wherey());
  1409.        printf("%d",i+1);
  1410.  
  1411.        length=PicMOffs[i+1]-PicMOffs[i];
  1412.        if (length>comp_size)
  1413.      errout("PICM is too big for the allocated buffer (compression)!");
  1414.        constlen+=length;
  1415.        oldlen+=length;
  1416.        fileoffs[Data[PICM].offset+i]=currentlen;
  1417.        *(long huge *)databuffer=length;
  1418.  
  1419.        if (!xmsok)
  1420.      LoadFile("PICM.TMP",lbmscreen,PicMOffs[i],length);
  1421.        else
  1422.      XMSmove(xmsSource,PicMOffs[i],0,(long)lbmscreen,length);
  1423.  
  1424.        //
  1425.        // Munge VGA ModeX graphics?
  1426.        //
  1427.        if (ModeX)
  1428.      VL_MungePic((unsigned char far *)lbmscreen,PicmTable[i].width,PicmTable[i].height);
  1429.  
  1430.        newlen=HuffCompress(lbmscreen,length,databuffer+4)+4;
  1431.  
  1432.        if (!xmsok)
  1433.      SaveFile(grname,databuffer,newlen,currentlen);
  1434.        else
  1435.      XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1436.  
  1437.        currentlen+=newlen;
  1438.        constcomp+=newlen;
  1439.        if ((bioskey(1)>>8)==1)
  1440.      {
  1441.       clrscr();
  1442.       errout("Aborted!");
  1443.      }
  1444.       }
  1445.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1446.  
  1447.     gotoxy(30,wherey());
  1448.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1449.     clreol();
  1450.    }
  1451.  cprintf("\n\r");
  1452. }
  1453.  
  1454.  
  1455. /////////////////////////////////////////////////////////
  1456. //
  1457. // Compress the SPRITES
  1458. //
  1459. /////////////////////////////////////////////////////////
  1460. void CompressSprites(void)
  1461. {
  1462.  if (Data[SPRITE].num)
  1463.    {
  1464.     long newlen,length;
  1465.  
  1466.     constlen=constcomp=0;
  1467.     gotoxy(30,wherey());
  1468.     printf("Compressing...");
  1469.  
  1470.  
  1471.     //
  1472.     // Stick Id Software ID bytes in!!!
  1473.     //
  1474.     SaveFile(grname,"!ID!",4,currentlen);
  1475.     currentlen+=4;
  1476.  
  1477.     xmsok=CheckXMSamount("SPRITE.TMP",&xmsSource,&xmsDest);
  1478.     if (xmsok)
  1479.       {
  1480.        printf("       (XMS cache)");
  1481.        startlen=currentlen;
  1482.       }
  1483.  
  1484.     for (i=0;i<Data[SPRITE].num;i++)
  1485.       {
  1486.        gotoxy(44,wherey());
  1487.        printf("%d",i+1);
  1488.  
  1489.        length=SpriteOffs[i+1]-SpriteOffs[i];
  1490.        if (length>comp_size)
  1491.      errout("SPRITE is too big for the allocated buffer (compression)!");
  1492.        constlen+=length;
  1493.        oldlen+=length;
  1494.        fileoffs[Data[SPRITE].offset+i]=currentlen;
  1495.        *(long huge *)databuffer=length;
  1496.  
  1497.        if (!xmsok)
  1498.      LoadFile("SPRITE.TMP",lbmscreen,SpriteOffs[i],length);
  1499.        else
  1500.      XMSmove(xmsSource,SpriteOffs[i],0,(long)lbmscreen,length);
  1501.  
  1502.        //
  1503.        // Munge VGA ModeX graphics?
  1504.        //
  1505.        if (ModeX)
  1506.      VL_MungePic((unsigned char far *)lbmscreen,SpriteTable[i].width,SpriteTable[i].height);
  1507.  
  1508.        newlen=HuffCompress(lbmscreen,length,databuffer+4)+4;
  1509.  
  1510.        if (!xmsok)
  1511.      SaveFile(grname,databuffer,newlen,currentlen);
  1512.        else
  1513.      XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1514.  
  1515.        currentlen+=newlen;
  1516.        constcomp+=newlen;
  1517.       }
  1518.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1519.  
  1520.     gotoxy(30,wherey());
  1521.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1522.     clreol();
  1523.    }
  1524.  cprintf("\n\r");
  1525. }
  1526.  
  1527.  
  1528. /////////////////////////////////////////////////////////
  1529. //
  1530. // Compress the TILE8s
  1531. //
  1532. /////////////////////////////////////////////////////////
  1533. void Compress8(void)
  1534. {
  1535.  if (Data[TILE8].num)
  1536.    {
  1537.     long newlen,length,spcount=0,clen=0;
  1538.  
  1539.  
  1540.     //
  1541.     // Stick Id Software ID bytes in!!!
  1542.     //
  1543.     SaveFile(grname,"!ID!",4,currentlen);
  1544.     currentlen+=4;
  1545.  
  1546.     if (!cmpt8)
  1547.       {
  1548.        int numsparse;
  1549.  
  1550.        gotoxy(30,wherey());
  1551.        printf("Compressing...");
  1552.  
  1553.        for (numsparse=i=0;i<Data[TILE8].num;i++)
  1554.      numsparse+=Sparse[TILE8*totalobjects+i];
  1555.  
  1556.        length=Data[TILE8].graphlen[gmode]*Data[TILE8].num-
  1557.           Data[TILE8].graphlen[gmode]*numsparse;
  1558.        oldlen+=length;
  1559.        constlen=length;
  1560.        fileoffs[Data[TILE8].offset]=currentlen;
  1561.        LoadFile("TILE8.TMP",lbmscreen,0,length);
  1562.        newlen=HuffCompress(lbmscreen,length,databuffer);
  1563.        SaveFile(grname,databuffer,newlen,currentlen);
  1564.        currentlen+=newlen;
  1565.        constcomp=newlen;
  1566.       }
  1567.     else
  1568.       {
  1569.        constlen=constcomp=0;
  1570.        gotoxy(30,wherey());
  1571.        printf("Compressing...");
  1572.  
  1573.        length=Data[TILE8].graphlen[gmode];
  1574.        for (i=0;i<Data[TILE8].num;i++)
  1575.      {
  1576.       gotoxy(44,wherey());
  1577.       printf("%d",i+1);
  1578.  
  1579.       if (Sparse[TILE8*totalobjects+i])
  1580.         {
  1581.          fileoffs[Data[TILE8].offset+i]=-1;
  1582.          spcount++;
  1583.         }
  1584.       else
  1585.         {
  1586.          oldlen+=length;
  1587.          constlen+=length;
  1588.          fileoffs[Data[TILE8].offset+i]=currentlen;
  1589.          LoadFile("TILE8.TMP",lbmscreen,clen,length);
  1590.          newlen=HuffCompress(lbmscreen,length,databuffer);
  1591.          SaveFile(grname,databuffer,newlen,currentlen);
  1592.          currentlen+=newlen;
  1593.          clen+=length;
  1594.          constcomp+=newlen;
  1595.         }
  1596.       if ((bioskey(1)>>8)==1)
  1597.         {
  1598.          clrscr();
  1599.          errout("Aborted!");
  1600.         }
  1601.      }
  1602.        allsparse+=spcount;
  1603.       }
  1604.     gotoxy(30,wherey());
  1605.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1606.     clreol();
  1607.    }
  1608.  cprintf("\n\r");
  1609.  
  1610.  if (Data[TILE8M].num)
  1611.    {
  1612.     long clen=0,newlen,length,spcount=0;
  1613.  
  1614.  
  1615.     //
  1616.     // Stick Id Software ID bytes in!!!
  1617.     //
  1618.     SaveFile(grname,"!ID!",4,currentlen);
  1619.     currentlen+=4;
  1620.  
  1621.     if (!cmpt8)
  1622.       {
  1623.        int numsparse;
  1624.  
  1625.        gotoxy(30,wherey());
  1626.        printf("Compressing...");
  1627.  
  1628.        for (numsparse=i=0;i<Data[TILE8M].num;i++)
  1629.      numsparse+=Sparse[TILE8M*totalobjects+i];
  1630.  
  1631.        length=Data[TILE8M].graphlen[gmode]*Data[TILE8M].num-
  1632.           Data[TILE8M].graphlen[gmode]*numsparse;
  1633.        constlen=length;
  1634.        oldlen+=length;
  1635.        fileoffs[Data[TILE8M].offset]=currentlen;
  1636.        LoadFile("TILE8M.TMP",lbmscreen,0,length);
  1637.        newlen=HuffCompress(lbmscreen,length,databuffer);
  1638.        SaveFile(grname,databuffer,newlen,currentlen);
  1639.        currentlen+=newlen;
  1640.        constcomp=newlen;
  1641.       }
  1642.     else
  1643.       {
  1644.        constlen=constcomp=0;
  1645.        gotoxy(30,wherey());
  1646.        printf("Compressing...");
  1647.  
  1648.        length=Data[TILE8M].graphlen[gmode];
  1649.        for (i=0;i<Data[TILE8M].num;i++)
  1650.      {
  1651.       gotoxy(44,wherey());
  1652.       printf("%d",i+1);
  1653.  
  1654.       if (Sparse[TILE8M*totalobjects+i])
  1655.         {
  1656.          fileoffs[Data[TILE8M].offset+i]=-1;
  1657.          spcount++;
  1658.         }
  1659.       else
  1660.         {
  1661.          constlen+=length;
  1662.          oldlen+=length;
  1663.          fileoffs[Data[TILE8M].offset+i]=currentlen;
  1664.          LoadFile("TILE8M.TMP",lbmscreen,clen,length);
  1665.          newlen=HuffCompress(lbmscreen,length,databuffer);
  1666.          SaveFile(grname,databuffer,newlen,currentlen);
  1667.          currentlen+=newlen;
  1668.          clen+=length;
  1669.          constcomp+=newlen;
  1670.         }
  1671.       if ((bioskey(1)>>8)==1)
  1672.         {
  1673.          clrscr();
  1674.          errout("Aborted!");
  1675.         }
  1676.      }
  1677.        allsparse+=spcount;
  1678.       }
  1679.     gotoxy(30,wherey());
  1680.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1681.     clreol();
  1682.    }
  1683.  cprintf("\n\r");
  1684. }
  1685.  
  1686.  
  1687. /////////////////////////////////////////////////////////
  1688. //
  1689. // Compress the TILE16s
  1690. //
  1691. /////////////////////////////////////////////////////////
  1692. void Compress16(void)
  1693. {
  1694.  if (Data[TILE16].num)
  1695.    {
  1696.     long clen=0,newlen,length,spcount=0;
  1697.  
  1698.     constlen=constcomp=0;
  1699.     gotoxy(30,wherey());
  1700.     printf("Compressing...");
  1701.  
  1702.  
  1703.     //
  1704.     // Stick Id Software ID bytes in!!!
  1705.     //
  1706.     SaveFile(grname,"!ID!",4,currentlen);
  1707.     currentlen+=4;
  1708.  
  1709.     xmsok=CheckXMSamount("TILE16.TMP",&xmsSource,&xmsDest);
  1710.     if (xmsok)
  1711.       {
  1712.        printf("       (XMS cache)");
  1713.        startlen=currentlen;
  1714.       }
  1715.  
  1716.     length=Data[TILE16].graphlen[gmode];
  1717.     for (i=0;i<Data[TILE16].num;i++)
  1718.       {
  1719.        gotoxy(44,wherey());
  1720.        printf("%d",i+1);
  1721.  
  1722.        if (Sparse[TILE16*totalobjects+i])
  1723.      {
  1724.       fileoffs[Data[TILE16].offset+i]=-1;
  1725.       spcount++;
  1726.      }
  1727.        else
  1728.      {
  1729.       constlen+=length;
  1730.       oldlen+=length;
  1731.       fileoffs[Data[TILE16].offset+i]=currentlen;
  1732.  
  1733.       if (!xmsok)
  1734.         LoadFile("TILE16.TMP",lbmscreen,clen,length);
  1735.       else
  1736.         XMSmove(xmsSource,clen,0,(long)lbmscreen,length);
  1737.  
  1738.       newlen=HuffCompress(lbmscreen,length,databuffer);
  1739.  
  1740.       if (!xmsok)
  1741.         SaveFile(grname,databuffer,newlen,currentlen);
  1742.       else
  1743.         XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1744.  
  1745.       currentlen+=newlen;
  1746.       clen+=length;
  1747.       constcomp+=newlen;
  1748.      }
  1749.        if ((bioskey(1)>>8)==1)
  1750.      {
  1751.       clrscr();
  1752.       errout("Aborted!");
  1753.      }
  1754.       }
  1755.  
  1756.     allsparse+=spcount;
  1757.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1758.  
  1759.     gotoxy(30,wherey());
  1760.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1761.     clreol();
  1762.    }
  1763.  cprintf("\n\r");
  1764.  
  1765.  if (Data[TILE16M].num)
  1766.    {
  1767.     long clen=0,newlen,length,spcount=0;
  1768.  
  1769.     constlen=constcomp=0;
  1770.     gotoxy(30,wherey());
  1771.     printf("Compressing...");
  1772.  
  1773.  
  1774.     //
  1775.     // Stick Id Software ID bytes in!!!
  1776.     //
  1777.     SaveFile(grname,"!ID!",4,currentlen);
  1778.     currentlen+=4;
  1779.  
  1780.     xmsok=CheckXMSamount("TILE16M.TMP",&xmsSource,&xmsDest);
  1781.     if (xmsok)
  1782.       {
  1783.        printf("       (XMS cache)");
  1784.        startlen=currentlen;
  1785.       }
  1786.  
  1787.     length=Data[TILE16M].graphlen[gmode];
  1788.     for (i=0;i<Data[TILE16M].num;i++)
  1789.       {
  1790.        gotoxy(44,wherey());
  1791.        printf("%d",i+1);
  1792.  
  1793.        if (Sparse[TILE16M*totalobjects+i])
  1794.      {
  1795.       fileoffs[Data[TILE16M].offset+i]=-1;
  1796.       spcount++;
  1797.      }
  1798.        else
  1799.      {
  1800.       constlen+=length;
  1801.       oldlen+=length;
  1802.       fileoffs[Data[TILE16M].offset+i]=currentlen;
  1803.  
  1804.       if (!xmsok)
  1805.         LoadFile("TILE16M.TMP",lbmscreen,clen,length);
  1806.       else
  1807.         XMSmove(xmsSource,clen,0,(long)lbmscreen,length);
  1808.  
  1809.       newlen=HuffCompress(lbmscreen,length,databuffer);
  1810.  
  1811.       if (!xmsok)
  1812.         SaveFile(grname,databuffer,newlen,currentlen);
  1813.       else
  1814.         XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1815.  
  1816.       currentlen+=newlen;
  1817.       clen+=length;
  1818.       constcomp+=newlen;
  1819.      }
  1820.        if ((bioskey(1)>>8)==1)
  1821.      {
  1822.       clrscr();
  1823.       errout("Aborted!");
  1824.      }
  1825.       }
  1826.  
  1827.     allsparse+=spcount;
  1828.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1829.  
  1830.     gotoxy(30,wherey());
  1831.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1832.     clreol();
  1833.    }
  1834.  cprintf("\n\r");
  1835. }
  1836.  
  1837.  
  1838. /////////////////////////////////////////////////////////
  1839. //
  1840. // Compress the TILE32s
  1841. //
  1842. /////////////////////////////////////////////////////////
  1843. void Compress32(void)
  1844. {
  1845.  if (Data[TILE32].num)
  1846.    {
  1847.     long clen=0,newlen,length,spcount=0;
  1848.  
  1849.     constlen=constcomp=0;
  1850.     gotoxy(30,wherey());
  1851.     printf("Compressing...");
  1852.  
  1853.  
  1854.     //
  1855.     // Stick Id Software ID bytes in!!!
  1856.     //
  1857.     SaveFile(grname,"!ID!",4,currentlen);
  1858.     currentlen+=4;
  1859.  
  1860.     xmsok=CheckXMSamount("TILE32.TMP",&xmsSource,&xmsDest);
  1861.     if (xmsok)
  1862.       {
  1863.        printf("       (XMS cache)");
  1864.        startlen=currentlen;
  1865.       }
  1866.  
  1867.     length=Data[TILE32].graphlen[gmode];
  1868.     for (i=0;i<Data[TILE32].num;i++)
  1869.       {
  1870.        gotoxy(44,wherey());
  1871.        printf("%d",i+1);
  1872.  
  1873.        if (Sparse[TILE32*totalobjects+i])
  1874.      {
  1875.       fileoffs[Data[TILE32].offset+i]=-1;
  1876.       spcount++;
  1877.      }
  1878.        else
  1879.      {
  1880.       constlen+=length;
  1881.       oldlen+=length;
  1882.       fileoffs[Data[TILE32].offset+i]=currentlen;
  1883.  
  1884.       if (!xmsok)
  1885.         LoadFile("TILE32.TMP",lbmscreen,clen,length);
  1886.       else
  1887.         XMSmove(xmsSource,clen,0,(long)lbmscreen,length);
  1888.  
  1889.       newlen=HuffCompress(lbmscreen,length,databuffer);
  1890.  
  1891.       if (!xmsok)
  1892.         SaveFile(grname,databuffer,newlen,currentlen);
  1893.       else
  1894.         XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1895.  
  1896.       currentlen+=newlen;
  1897.       clen+=length;
  1898.       constcomp+=newlen;
  1899.      }
  1900.        if ((bioskey(1)>>8)==1)
  1901.      {
  1902.       clrscr();
  1903.       errout("Aborted!");
  1904.      }
  1905.       }
  1906.  
  1907.     allsparse+=spcount;
  1908.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1909.  
  1910.     gotoxy(30,wherey());
  1911.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1912.     clreol();
  1913.    }
  1914.  cprintf("\n\r");
  1915.  
  1916.  if (Data[TILE32M].num)
  1917.    {
  1918.     long clen=0,newlen,length,spcount=0;
  1919.  
  1920.     constlen=constcomp=0;
  1921.     gotoxy(30,wherey());
  1922.     printf("Compressing...");
  1923.  
  1924.  
  1925.     //
  1926.     // Stick Id Software ID bytes in!!!
  1927.     //
  1928.     SaveFile(grname,"!ID!",4,currentlen);
  1929.     currentlen+=4;
  1930.  
  1931.     xmsok=CheckXMSamount("TILE32M.TMP",&xmsSource,&xmsDest);
  1932.     if (xmsok)
  1933.       {
  1934.        printf("       (XMS cache)");
  1935.        startlen=currentlen;
  1936.       }
  1937.  
  1938.     length=Data[TILE32M].graphlen[gmode];
  1939.     for (i=0;i<Data[TILE32M].num;i++)
  1940.       {
  1941.        gotoxy(44,wherey());
  1942.        printf("%d",i+1);
  1943.  
  1944.        if (Sparse[TILE32M*totalobjects+i])
  1945.      {
  1946.       fileoffs[Data[TILE32M].offset+i]=-1;
  1947.       spcount++;
  1948.      }
  1949.        else
  1950.      {
  1951.       constlen+=length;
  1952.       oldlen+=length;
  1953.       fileoffs[Data[TILE32M].offset+i]=currentlen;
  1954.  
  1955.       if (!xmsok)
  1956.         LoadFile("TILE32M.TMP",lbmscreen,clen,length);
  1957.       else
  1958.         XMSmove(xmsSource,clen,0,(long)lbmscreen,length);
  1959.  
  1960.       newlen=HuffCompress(lbmscreen,length,databuffer);
  1961.  
  1962.       if (!xmsok)
  1963.         SaveFile(grname,databuffer,newlen,currentlen);
  1964.       else
  1965.         XMSmove(0,(long)databuffer,xmsDest,currentlen-startlen,newlen);
  1966.  
  1967.       currentlen+=newlen;
  1968.       clen+=length;
  1969.       constcomp+=newlen;
  1970.      }
  1971.        if ((bioskey(1)>>8)==1)
  1972.      {
  1973.       clrscr();
  1974.       errout("Aborted!");
  1975.      }
  1976.       }
  1977.  
  1978.     allsparse+=spcount;
  1979.     FreeXMSbuffs(&xmsSource,&xmsDest,grname,startlen,currentlen-startlen);
  1980.  
  1981.     gotoxy(30,wherey());
  1982.     printf("Compressed %lu to %lu.",constlen,constcomp);
  1983.     clreol();
  1984.    }
  1985.  cprintf("\n\r");
  1986. }
  1987.  
  1988.  
  1989. /////////////////////////////////////////////////////////
  1990. //
  1991. // Setup the FinishUp function
  1992. //
  1993. /////////////////////////////////////////////////////////
  1994. void SetupFinish(void)
  1995. {
  1996.  //
  1997.  // HANDLE "END" KEYWORD
  1998.  //
  1999.  if (lumpactive)
  2000.    errout("You didn't ENDLUMP before ENDing your script!");
  2001.  
  2002.  
  2003.  if (maskscreen!=NULL)
  2004.    farfree((void far *)maskscreen);
  2005.  if (lbmscreen!=NULL)
  2006.    farfree((void far *)lbmscreen);
  2007.  
  2008.  lbmscreen=(char huge *)farmalloc(comp_size);
  2009.  
  2010.  if ((fileoffs=(long huge *)farmalloc((totalobjects+1)*4L))==NULL)
  2011.    errout("Not enough memory to allocate massive FILEOFF array!");
  2012.  
  2013.  if (!begin)
  2014.    errout("How can you END when you haven't even BEGUN?");
  2015.  
  2016.  //
  2017.  // See if Extended memory is present
  2018.  //
  2019.  xms=0;
  2020.  if (!InitXMS())
  2021.    xms=1;
  2022.  
  2023.  //
  2024.  // Compress everything
  2025.  //
  2026.  if (!noshow)
  2027.    {
  2028.     settext();
  2029.     DispStatusScreen();
  2030.    }
  2031.  
  2032.  clrscr();
  2033.  vtab=wherey();
  2034.  cprintf("FONTs    grabbed: %d\n\r",Data[FONT].num);
  2035.  cprintf("FONTMs   grabbed: %d\n\r",Data[FONTM].num);
  2036.  cprintf("PICs     grabbed: %d\n\r",Data[PIC].num);
  2037.  cprintf("PICMs    grabbed: %d\n\r",Data[PICM].num);
  2038.  cprintf("SPRITEs  grabbed: %d\n\r",Data[SPRITE].num);
  2039.  cprintf("TILE8s   grabbed: %d\n\r",Data[TILE8].num);
  2040.  cprintf("TILE8Ms  grabbed: %d\n\r",Data[TILE8M].num);
  2041.  cprintf("TILE16s  grabbed: %d\n\r",Data[TILE16].num);
  2042.  cprintf("TILE16Ms grabbed: %d\n\r",Data[TILE16M].num);
  2043.  cprintf("TILE32s  grabbed: %d\n\r",Data[TILE32].num);
  2044.  cprintf("TILE32Ms grabbed: %d\n\r",Data[TILE32M].num);
  2045.  cprintf("MISC DATA import: %d",NumMisc);
  2046.  gotoxy(2,vtab);
  2047.  
  2048.  grname[0]=format[0];
  2049.  grname[1]=0;
  2050.  strcat(grname,"GAGRAPH.");
  2051.  strcat(grname,ext);
  2052. }
  2053.  
  2054.  
  2055. /////////////////////////////////////////////////////////
  2056. //
  2057. // Create the Fileoffs array & count remaining databytes
  2058. //
  2059. /////////////////////////////////////////////////////////
  2060. void CreateOffsets(void)
  2061. {
  2062.  CountBytes((unsigned char huge *)PicTable,Data[PIC].num*sizeof(PicStruct));
  2063.  CountBytes((unsigned char huge *)PicmTable,Data[PICM].num*sizeof(PicStruct));
  2064.  CountBytes((unsigned char huge *)&SpriteTable,Data[SPRITE].num*sizeof(SprStruct));
  2065.  
  2066.  Huffmanize();    // create the dictionary
  2067.  //
  2068.  // create pointer-table indexes
  2069.  //
  2070.  start=(Data[PIC].num>0)+
  2071.        (Data[PICM].num>0)+
  2072.        (Data[SPRITE].num>0)+
  2073.        (bit && T8whichbit)+
  2074.        (bit && T16whichbit)+
  2075.        (bit && T32whichbit);
  2076.  
  2077.  Data[FONT].offset=start;
  2078.  Data[FONTM].offset=Data[FONT].offset+Data[FONT].num;
  2079.  Data[PIC].offset=Data[FONTM].offset+Data[FONTM].num;
  2080.  Data[PICM].offset=Data[PIC].offset+Data[PIC].num;
  2081.  Data[SPRITE].offset=Data[PICM].offset+Data[PICM].num;
  2082.  Data[TILE8].offset=Data[SPRITE].offset+Data[SPRITE].num;
  2083.  
  2084.  if (!cmpt8)
  2085.    {
  2086.     Data[TILE8M].offset=Data[TILE8].offset+1*(Data[TILE8].num>0);// tile8's are special
  2087.     Data[TILE16].offset=Data[TILE8M].offset+1*(Data[TILE8M].num>0);
  2088.    }
  2089.  else
  2090.    {
  2091.     Data[TILE8M].offset=Data[TILE8].offset+Data[TILE8].num;    // now they're not!
  2092.     Data[TILE16].offset=Data[TILE8M].offset+Data[TILE8M].num;
  2093.    }
  2094.  
  2095.  Data[TILE16M].offset=Data[TILE16].offset+Data[TILE16].num;
  2096.  Data[TILE32].offset=Data[TILE16M].offset+Data[TILE16M].num;
  2097.  Data[TILE32M].offset=Data[TILE32].offset+Data[TILE32].num;
  2098.  
  2099.  if (Data[TILE32M].offset+Data[TILE32M].num>totalobjects)
  2100.    {
  2101.     char tmpstr[]="ERROR! Not enough space allocated for OFFSETTABLE. Talk to John R.!\nYou need space for ",
  2102.     poop[10];
  2103.  
  2104.     ltoa(Data[TILE32M].offset+Data[TILE32M].num,poop,10);
  2105.     strcat(tmpstr,poop);
  2106.     strcat(tmpstr," objects, pal.");
  2107.     clrscr();
  2108.     errout(tmpstr);
  2109.    }
  2110.  
  2111.  for (i=0;i<totalobjects+1;i++)
  2112.    fileoffs[i]=0;
  2113. }
  2114.  
  2115.  
  2116. /////////////////////////////////////////////////////////
  2117. //
  2118. // Compress all the STRUCTS and BIT ARRAYS
  2119. //
  2120. /////////////////////////////////////////////////////////
  2121. void CompressSpecial(void)
  2122. {
  2123.  start=0;
  2124.  
  2125.  //
  2126.  // Compress the SPECIAL CHUNKS
  2127.  //
  2128.  if (Data[PIC].num)
  2129.    {
  2130.     long newlen,length=Data[PIC].num*sizeof(PicStruct);
  2131.  
  2132.     fileoffs[start]=currentlen;
  2133.     *(long huge *)databuffer=length;
  2134.     newlen=HuffCompress((char huge *)PicTable,length,databuffer+4);
  2135.     SaveFile(grname,databuffer,newlen+4,currentlen);
  2136.     currentlen+=newlen+4;
  2137.     start++;
  2138.    }
  2139.  if (Data[PICM].num)
  2140.    {
  2141.     long newlen,length=Data[PICM].num*sizeof(PicStruct);
  2142.  
  2143.     fileoffs[start]=currentlen;
  2144.     *(long huge *)databuffer=length;
  2145.     newlen=HuffCompress((char huge *)PicmTable,length,databuffer+4);
  2146.     SaveFile(grname,databuffer,newlen+4,currentlen);
  2147.     currentlen+=newlen+4;
  2148.     start++;
  2149.    }
  2150.  if (Data[SPRITE].num)
  2151.    {
  2152.     long newlen,length=Data[SPRITE].num*sizeof(SprStruct);
  2153.  
  2154.     fileoffs[start]=currentlen;
  2155.     *(long huge *)databuffer=length;
  2156.     newlen=HuffCompress((char huge *)&SpriteTable,length,databuffer+4);
  2157.     SaveFile(grname,databuffer,newlen+4,currentlen);
  2158.     currentlen+=newlen+4;
  2159.     start++;
  2160.    }
  2161.  if (bit && T8whichbit)
  2162.    {
  2163.     long newlen,length=(T8whichbit+7)/8;
  2164.  
  2165.     fileoffs[start]=currentlen;
  2166.     *(long huge *)databuffer=length;
  2167.     newlen=HuffCompress((char huge *)T8bit,length,databuffer+4);
  2168.     SaveFile(grname,databuffer,newlen+4,currentlen);
  2169.     currentlen+=newlen+4;
  2170.     start++;
  2171.    }
  2172.  if (bit && T16whichbit)
  2173.    {
  2174.     long newlen,length=(T16whichbit+7)/8;
  2175.  
  2176.     fileoffs[start]=currentlen;
  2177.     *(long huge *)databuffer=length;
  2178.     newlen=HuffCompress((char huge *)T16bit,length,databuffer+4);
  2179.     SaveFile(grname,databuffer,newlen+4,currentlen);
  2180.     currentlen+=newlen+4;
  2181.     start++;
  2182.    }
  2183.  if (bit && T32whichbit)
  2184.    {
  2185.     long newlen,length=(T32whichbit+7)/8;
  2186.  
  2187.     fileoffs[start]=currentlen;
  2188.     *(long huge *)databuffer=length;
  2189.     newlen=HuffCompress((char huge *)T32bit,length,databuffer+4);
  2190.     SaveFile(grname,databuffer,newlen+4,currentlen);
  2191.     currentlen+=newlen+4;
  2192.     start++;
  2193.    }
  2194. }
  2195.  
  2196.  
  2197. /////////////////////////////////////////////////////////
  2198. //
  2199. // Compress the Miscellaneous Data
  2200. //
  2201. /////////////////////////////////////////////////////////
  2202. void CompressMisc(void)
  2203. {
  2204.  int start,i;
  2205.  long len,newlen,constcomp,constlen;
  2206.  char temp[NAMELEN];
  2207.  
  2208.  
  2209.  if (!NumMisc)
  2210.    return;
  2211.  
  2212.  constlen=constcomp=0;
  2213.  gotoxy(30,wherey());
  2214.  printf("Compressing...");
  2215.  
  2216.  start=Data[TILE32M].offset+Data[TILE32M].num;
  2217.  for (i=0;i<NumMisc;i++)
  2218.    {
  2219.     gotoxy(44,wherey());
  2220.     printf("%d",i+1);
  2221.  
  2222.     _fstrcpy((char far *)temp,(char far *)MiscFNames+i*NAMELEN);
  2223.     fileoffs[i+start]=currentlen;
  2224.     len=filelen(temp);
  2225.     constlen+=len;
  2226.     LoadFile(temp,lbmscreen,0,0);
  2227.     *(long huge *)databuffer=len;
  2228.     newlen=HuffCompress(lbmscreen,len,databuffer+4)+4;
  2229.     SaveFile(grname,databuffer,newlen,currentlen);
  2230.     constcomp+=newlen;
  2231.     currentlen+=newlen;
  2232.    }
  2233.  
  2234.  gotoxy(30,wherey());
  2235.  printf("Compressed %lu to %lu.",constlen,constcomp);
  2236.  clreol();
  2237.  
  2238.  // MAKE SURE WE STICK THE LAST ONE IN!
  2239.  fileoffs[start+NumMisc]=currentlen;
  2240. }
  2241.  
  2242.  
  2243. /////////////////////////////////////////////////////////
  2244. //
  2245. // Create the ?GAHEAD,?GADICT,TEDINFO? files
  2246. //
  2247. /////////////////////////////////////////////////////////
  2248. void CreateGraphFiles(void)
  2249. {
  2250.  //
  2251.  // Create "xGAHEAD.EXT"
  2252.  //
  2253.  strcpy(dest,"?GAHEAD.");
  2254.  dest[0]=format[0];
  2255.  strcat(dest,ext);
  2256.  dest[12]=0;
  2257.  
  2258.  //
  2259.  // Save "xGAHEAD.EXT"
  2260.  //
  2261.  strcpy(headname,dest);
  2262.  unlink(dest);
  2263.  if ((handle=_creat(dest,FA_ARCH))==-1)
  2264.    {
  2265.     char msg[80]="Couldn't create '";
  2266.  
  2267.     strcat(msg,dest);
  2268.     strcat(msg,"!");
  2269.     errout(msg);
  2270.    }
  2271.  
  2272.  if (!cmpt8)
  2273.    numall=Data[FONT].num+
  2274.       Data[FONTM].num+
  2275.       (Data[TILE8].num>0)+
  2276.       (Data[TILE8M].num>0)+
  2277.       Data[TILE16].num+
  2278.       Data[TILE16M].num+
  2279.       Data[TILE32].num+
  2280.       Data[TILE32M].num+
  2281.       Data[PIC].num+
  2282.       Data[PICM].num+
  2283.       Data[SPRITE].num+
  2284.       (Data[PIC].num>0)+
  2285.       (Data[PICM].num>0)+
  2286.       (Data[SPRITE].num>0)+
  2287.       (bit && T8whichbit)+
  2288.       (bit && T16whichbit)+
  2289.       (bit && T32whichbit)+
  2290.       NumMisc;
  2291.  
  2292.  else
  2293.    numall=Data[FONT].num+
  2294.       Data[FONTM].num+
  2295.       Data[TILE8].num+
  2296.       Data[TILE8M].num+
  2297.       Data[TILE16].num+
  2298.       Data[TILE16M].num+
  2299.       Data[TILE32].num+
  2300.       Data[TILE32M].num+
  2301.       Data[PIC].num+
  2302.       Data[PICM].num+
  2303.       Data[SPRITE].num+
  2304.       (Data[PIC].num>0)+
  2305.       (Data[PICM].num>0)+
  2306.       (Data[SPRITE].num>0)+
  2307.       (bit && T8whichbit)+
  2308.       (bit && T16whichbit)+
  2309.       (bit && T32whichbit)+
  2310.       NumMisc;
  2311.  
  2312.  close(handle);
  2313.  //
  2314.  // 3-byte Offsets?
  2315.  //
  2316.  if (!Do4offs)
  2317.  {
  2318.   unsigned i;
  2319.   char huge *newoffs;
  2320.  
  2321.   if ((newoffs=farmalloc(3L*(numall+1)))==NULL)
  2322.     errout("Not enough memory to create 3-byte OFFSETS!");
  2323.  
  2324.   for (i=0;i<numall+1;i++)
  2325.     *(long huge *)(newoffs+3L*i)=fileoffs[i];
  2326.  
  2327.   SaveFile(dest,(char huge *)newoffs,3L*(numall+1),0);
  2328.  }
  2329.  else
  2330.    SaveFile(dest,(char huge *)fileoffs,4*(numall+1),0);
  2331.  
  2332.  //
  2333.  // Create EGADICT.ext file
  2334.  //
  2335.  {
  2336.   char name[14]="?GADICT.";
  2337.  
  2338.   name[0]=format[0];
  2339.   strcat(name,ext);
  2340.   SaveFile(name,(char huge *)&nodearray,sizeof(nodearray),0);
  2341.  }
  2342.  
  2343.  //
  2344.  // Create GFXINFO?.ext file
  2345.  //
  2346.  {
  2347.   char name[14]="GFXINFO?.";
  2348.   InfoStruct huge *infofile;
  2349.  
  2350.   if((infofile=(InfoStruct huge *)farmalloc(sizeof(InfoStruct)))==NULL)
  2351.     errout("Not enough memory to create GFXINFO file!");
  2352.  
  2353.   _fmemset((void far *)infofile,0,sizeof(InfoStruct));
  2354.   infofile->num8=Data[TILE8].num;
  2355.   infofile->num8m=Data[TILE8M].num;
  2356.   infofile->num16=Data[TILE16].num;
  2357.   infofile->num16m=Data[TILE16M].num;
  2358.   infofile->num32=Data[TILE32].num;
  2359.   infofile->num32m=Data[TILE32M].num;
  2360.  
  2361.   infofile->off8=Data[TILE8].offset;
  2362.   infofile->off8m=Data[TILE8M].offset;
  2363.   infofile->off16=Data[TILE16].offset;
  2364.   infofile->off16m=Data[TILE16M].offset;
  2365.   infofile->off32=Data[TILE32].offset;
  2366.   infofile->off32m=Data[TILE32M].offset;
  2367.  
  2368.   infofile->numpics=Data[PIC].num;
  2369.   infofile->numpicm=Data[PICM].num;
  2370.   infofile->numsprites=Data[SPRITE].num;
  2371.  
  2372.   infofile->offpic=Data[PIC].offset;
  2373.   infofile->offpicm=Data[PICM].offset;
  2374.   infofile->offsprites=Data[SPRITE].offset;
  2375.  
  2376.   infofile->numexterns=NumMisc;
  2377.   infofile->offexterns=Data[TILE32M].offset+Data[TILE32M].num;
  2378.  
  2379.   name[7]=format[0];
  2380.   strcat(name,ext);
  2381.   SaveFile(name,(char huge *)infofile,sizeof(InfoStruct),0);
  2382.  }
  2383. }
  2384.  
  2385.  
  2386. /////////////////////////////////////////////////////////
  2387. //
  2388. // Create OBJ files if requested
  2389. //
  2390. /////////////////////////////////////////////////////////
  2391. void CreateOBJs(void)
  2392. {
  2393.  //
  2394.  // GENERATE 2 .OBJ FILES?
  2395.  //
  2396.  if (genobj)
  2397.    {
  2398.     char newname[24],pubname[25],farname[25],dname[13];
  2399.  
  2400.     //
  2401.     // Header
  2402.     //
  2403.     strcpy(newname,ext);
  2404.     strcat(newname,format);
  2405.     strcat(newname,"HEAD.OBJ");
  2406.  
  2407.     strcpy(pubname,"_");
  2408.     strcat(pubname,format);
  2409.     strcat(pubname,"GAhead");
  2410.  
  2411.     strcpy(farname,format);
  2412.     strcat(farname,"GA_grafixheader");
  2413.  
  2414.     if (MakeOBJ(headname,newname,pubname,FARDATA,farname)>0)
  2415.       errout("Error making Header OBJ file!");
  2416.  
  2417.  
  2418.     //
  2419.     // Dictionary
  2420.     //
  2421.     strcpy(dname,format);
  2422.     strcat(dname,"GADICT.");
  2423.     strcat(dname,ext);
  2424.  
  2425.     strcpy(newname,ext);
  2426.     strcat(newname,format);
  2427.     strcat(newname,"DICT.OBJ");
  2428.  
  2429.     strcpy(pubname,"_");
  2430.     strcat(pubname,format);
  2431.     strcat(pubname,"GAdict");
  2432.  
  2433.     if (MakeOBJ(dname,newname,pubname,DATA,"")>0)
  2434.       errout("Error making Dictionary OBJ file!");
  2435.  
  2436.     gotoxy(2,19);
  2437.     printf("OBJ files created.\n");
  2438.    }
  2439. }
  2440.  
  2441.  
  2442. /////////////////////////////////////////////////////////
  2443. //
  2444. // Update the IGRAB grabwindow
  2445. //
  2446. /////////////////////////////////////////////////////////
  2447. void UpdateWindow(void)
  2448. {
  2449.  window(1,1,80,25);
  2450.  gotoxy(30,21);
  2451.  cprintf("%lu",oldlen);
  2452.  gotoxy(64,21);
  2453.  cprintf("%lu",currentlen);
  2454.  gotoxy(25,22);
  2455.  cprintf("%d",allsparse);
  2456.  gotoxy(59,22);
  2457.  cprintf("%d",allsparse*4);
  2458.  
  2459.  gotoxy(60,6);
  2460.  cprintf("%d",numall);
  2461. }
  2462.  
  2463.  
  2464.  
  2465. /*
  2466. =================
  2467. =
  2468. = VL_MungePic
  2469. =
  2470. =================
  2471. */
  2472. void VL_MungePic (unsigned char far *source, unsigned width, unsigned height)
  2473. {
  2474.     unsigned    x,y,plane,size,pwidth;
  2475.     unsigned char    far *temp, far *dest, far *srcline;
  2476.  
  2477.     size = width*height;
  2478.  
  2479.     if (width&3)
  2480.         errout ("VL_MungePic: Not divisable by 4!\n");
  2481.  
  2482. //
  2483. // copy the pic to a temp buffer
  2484. //
  2485.     temp = (unsigned char far *)farmalloc (size);
  2486.     if (!temp)
  2487.         errout ("Non enough memory for munge buffer!\n");
  2488.  
  2489.     _fmemcpy (temp,source,size);
  2490.  
  2491. //
  2492. // munge it back into the original buffer
  2493. //
  2494.     dest = source;
  2495.     pwidth = width/4;
  2496.  
  2497.     for (plane=0;plane<4;plane++)
  2498.     {
  2499.         srcline = temp;
  2500.         for (y=0;y<height;y++)
  2501.         {
  2502.             for (x=0;x<pwidth;x++)
  2503.                 *dest++ = *(srcline+x*4+plane);
  2504.             srcline+=width;
  2505.         }
  2506.     }
  2507.  
  2508.     farfree (temp);
  2509. }
  2510.  
  2511.